import path from 'path';
import { config } from "dotenv";
// config({ path: "../../dataBase/.env" });
import chokidar from "chokidar";
import { execSync } from "child_process";
import { h, remotePath, root, serverName, jarName } from "./config";
import { ssh } from "./ssh";
import { genEntity, ts, tsa } from "./watch";

const option: Option[] = [
  // { path: path.resolve(root, serviceImplPath), u: jssic, }, // 服务实体
  // { path: path.resolve(root, "api/default.sql"), u: apiSql, }, // 监视sql文件
  // { path: path.resolve(root, "api/src"), c: apicu, u: apicu, d: apid }, // 监视api/src文件
  { path: path.resolve(root, "plugin/src"), c: main, u: main, d: main } // 本项目自动运行
];
function findEntity(fullName: string) {
  return option.find(e => !fullName.indexOf(e.path));
}
function runWatch() {
  const wfs = option.map(e => e.path);
  console.log("监控启动", wfs);
  return chokidar.watch(wfs, {
    ignored: /(^|[\/\\])\../, // 忽略隐藏文件和目录
    persistent: true, // 默认为true，即使没有事件触发也保持程序运行
    ignoreInitial: true, // 是否忽略最初添加的文件和目录事件
    followSymlinks: true, // 是否跟随符号链接
    usePolling: true, // 在某些情况下（如网络文件系统）启用轮询而不是FS事件
    alwaysStat: true, // 获取每次文件更改的fs.Stats对象
    // depth: 0, // 监控深度，默认为∞，设为0则不监控子目录
  })
    .on('add', path => {
      const e = findEntity(path);
      if (e && e.c instanceof Function) {
        e.c(path, path.substring(e.path.length + 1, path.lastIndexOf(".")));
      } else {
        console.log("创建", "错误:", path, e);
      }
    })
    .on('change', path => {
      const e = findEntity(path);
      if (e && e.u instanceof Function) {
        e.u(path, path.substring(e.path.length + 1, path.lastIndexOf(".")));
      } else {
        console.log("修改", "错误:", path);
      }
    })
    .on('unlink', path => {
      const e = findEntity(path);
      if (e && e.d instanceof Function) {
        e.d(path, path.substring(e.path.length + 1, path.lastIndexOf(".")));
      } else {
        console.log("删除", "错误:", path);
      }
    })
    .on('error', error => {
      console.log("错误", error);
    });
}
// unzip -q -o ./api/api.zip -d ./api/ && echo zipSuccess
export async function upApi() {
  const
    apiPath = path.resolve(root, "api/"),
    st = new Date().getTime();
  let lt = new Date().getTime();
  console.log(await ssh.shell(`/root/bt.sh stopJava ${serverName}`), "耗时:", (new Date().getTime() - lt) / 1000, "秒");
  console.log("打包中");
  lt = new Date().getTime();
  execSync(`mvn clean package -f ${path.resolve(apiPath, "pom.xml")}`, { stdio: "ignore" });
  console.log("打包完成", "耗时:", (new Date().getTime() - lt) / 1000, "秒");
  lt = new Date().getTime();
  await ssh.upFile(path.resolve(apiPath, `target/${jarName}`), `${remotePath}/${jarName}`);
  console.log("耗时:", (new Date().getTime() - lt) / 1000, "秒");

  lt = new Date().getTime();
  console.log(await ssh.shell(`/root/bt.sh startJava ${serverName}`), "耗时:", (new Date().getTime() - lt) / 1000, "秒");

  console.log("总耗时:", (new Date().getTime() - st) / 1000, "秒");
  process.exit(0);
}
export async function rec() {
  let lt = new Date().getTime();
  console.log(await ssh.shell(`/root/bt.sh restartJava ${serverName}`), "耗时:", (new Date().getTime() - lt) / 1000, "秒");
  process.exit(0);
}
async function main() {
  console.clear();
  if (config instanceof Function) {
    console.log(config({ path: "../dataBase/.env" }));
    process.exit(0);
    return;
  }
  if (h.watch) {
    h.watch.close();
    console.clear();
    console.log("重新启动");
    setTimeout(() => {
      process.exit();
    }, 100);
    execSync("npm run dev", { cwd: path.resolve(root, "plugin"), stdio: "inherit" });
    return;
  }
  h.watch = runWatch();
  genEntity(path.resolve(root, "api/default.sql"));
}

async function sql(tableName?: string) {
  genEntity(path.resolve(root, "api/default.sql"), tableName);
  process.exit(0);
}

function run() {
  switch (process.argv[2]) {
    case "re": upApi(); break;
    case "rec": rec(); break;
    case "sql": sql(process.argv[3]); break;
    case "ts": ts(process.argv[3], process.argv[4]); break;
    case "tsa": tsa(); break;
    default: main(); break;
  }
}
run();
